package com.fable.web.interceptor;

import com.alibaba.fastjson.JSON;
import com.fable.common.config.RequireLogin;
import com.fable.common.constant.FableConstant;
import com.fable.common.enums.BusiErrCode;
import com.fable.common.utils.JsonResult;
import com.fable.dal.dto.AdminUserDTO;
import com.fable.dal.model.AdminDO;
import com.fable.dal.model.AdminUserDO;
import com.fable.utils.WebUtil;
import com.fable.web.page.P;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.fable.common.constant.FableConstant;

/**
 * 拦截并配置加载当前登录用户，静态资源，以及velocity模板对象
 */
public class WebConfigInterceptor extends HandlerInterceptorAdapter implements InitializingBean, ApplicationContextAware {

    private static final Logger LOG = LoggerFactory.getLogger(WebConfigInterceptor.class);

    @Value("${fable.assets.url}")
    private String assetsUrl;

    @Value("${fable.assets.img.url}")
    private String assetsImgUrl;

    @Value("${fable.assets.img.https.url}")
    private String assetsHttpsImgUrl;

    @Value("${fable.service.url}")
    private String servicerUrl;



    /**
     * 获取当前上下文
     */
    private ApplicationContext applicationContext;


    @Override
    public void afterPropertiesSet() throws Exception {
        //todo
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (modelAndView != null && modelAndView.getViewName() != null && !modelAndView.getViewName().startsWith("redirect:")) {
            //modelAndView.addObject("base", request.getContextPath());
            // 添加view至上下文中，用以解析velocity的module模板
//            modelAndView.addObject("view", new ViewModuleTool(request, response, applicationContext));
            modelAndView.addObject(FableConstant.ASSETS_URL, assetsUrl);
            modelAndView.addObject(FableConstant.ASSETS_IMG_URL, assetsImgUrl);
            modelAndView.addObject(FableConstant.ASSETS_HTTPS_IMG_URL, assetsHttpsImgUrl);
            modelAndView.addObject(FableConstant.ASSETS_HTTPS_IMG_URL, assetsHttpsImgUrl);
            modelAndView.addObject(FableConstant.HOME_URl,servicerUrl );
            //todo  timestamp 可以从数据库或缓存读取
            modelAndView.addObject(FableConstant.TIMESTAMP, "2015031610");

            try {
                AdminUserDTO adminUserDTO =(AdminUserDTO)request.getSession().getAttribute(FableConstant.USER_SESSION_KEY);
                if(adminUserDTO!=null){
                    modelAndView.addObject("admin",adminUserDTO);
                }
            } catch (Exception e) {
                LOG.error("拦截器获取role异常");
            }
        }
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        putUserInfo(request);


        if (handler instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod) handler;
            // 不需要登录验证时可以访问，否则回到登录页面
            if (!isRequireLogin(method) || isAuthenticated(request)) {
                return true;
            }

            if (!isRequireLogin(method)) {
                return true;
            }

            try {
                if (WebUtil.isJson(request)) {
                    JsonResult jsonResult = JsonResult.getInstance();
                    jsonResult.setRedirectUrl(WebUtil.getRedirectUrlFromReferer(request, P.RedirectUrl.login));
                    jsonResult.setErrCode(BusiErrCode.NO_LOGIN);
                    WebUtil.writerJson(response, JSON.toJSONString(jsonResult.getMap()));
                } else {
                    UriComponentsBuilder builder = ServletUriComponentsBuilder.fromContextPath(request).path("/login.htm");
                    String redirectURL=ServletUriComponentsBuilder.fromRequest(request).build().encode().toUriString();
                    LOG.debug("servicerUrl:{}",servicerUrl);
                    if(StringUtils.isNotBlank(redirectURL)&&!"/".equals(redirectURL)&&!servicerUrl.equals(redirectURL)&&!"http://47.98.173.37:8080/".equals(redirectURL)&&!"http://msrz.top:8080/".equals(redirectURL)){
                        builder.queryParam("redirectURL", redirectURL);
                    }
                    response.sendRedirect(builder.build().encode().toUriString());
                }
            } catch (Exception e) {
                LOG.error("deal redirect error!", e);
            }

            return false;
        }
        return true;
    }

    private void putUserInfo(HttpServletRequest request) {
//        try {
//            Long loginUserId = CurrentUserUtil.getLoginUserId(request);
//            BizResult<AccountInfoDTO> bizResult = accountService.getAccountInfoFromCache(loginUserId);
//            // 如果缓存/数据库获取失败，删除登陆用户
//            if (!bizResult.isSuccess()) {
//                Context.removeAccountInfo();
//                return;
//            }
//
//            // 设置当前登陆用户
//            Context.putAccountInfo(bizResult.getData());
//        } catch (Exception e) {
//            LOG.error("put login user error!", e);
//        }

    }

    /**
     * 登陆、且状态有效
     *
     * @return
     */
    private boolean isAuthenticated(HttpServletRequest request) {
        HttpSession session=request.getSession();

        AdminUserDTO adminUserDTO  = (AdminUserDTO) session.getAttribute(FableConstant.USER_SESSION_KEY);
        if(adminUserDTO!=null){
            return true;
        }
        return false;

    }

    /**
     * 判断是否需要登录验证
     */
    private boolean isRequireLogin(HandlerMethod handler) throws Exception {
        boolean isRequireLogin = false;
        Class<?> beanClass = handler.getBeanType();
        if (beanClass.isAnnotationPresent(RequireLogin.class)) {
            isRequireLogin = true;
        } else {
            RequireLogin requireLoginAnnotation = handler.getMethodAnnotation(RequireLogin.class);
            if (requireLoginAnnotation != null) {
                isRequireLogin = true;
            }
        }
        return isRequireLogin;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
